﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Linq;
using System.Net.Configuration;
using System.Text;
using System.Web;
using System.Web.Configuration;
using System.Web.UI;
using System.Web.UI.WebControls;

using ActiveUp.Net.Mail;

using Microsoft.Practices.EnterpriseLibrary.Common;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging;


namespace TractRecord.Service
{
    public partial class CheckMail : TractRecordPage
    {
        int validEmails = 0;
        int invalidEmails = 0;
        int nonActiveEmails = 0;

        protected void Page_Load(object sender, EventArgs e)
        {
            Code.Common.Log("Check Mail Routine Starting.", "Check Mail", 0, 0, System.Diagnostics.TraceEventType.Information, "Check Mail");

            try
            {
                RunCheck();
            }
            catch (Exception ex)
            {
                Code.Common.Log(ex.ToString(), ex.GetType().ToString(), 100, 0, System.Diagnostics.TraceEventType.Critical, "Upload File Error"); 
            }
        }

        protected void Page_Unload(object sender, EventArgs e)
        {
            Code.Common.Log("Check Mail Routine Completing.", "Check Mail", 0, 0, System.Diagnostics.TraceEventType.Information, "Check Mail Routine Completed");
            Code.Common.Log(validEmails + ": valid emails processed.", "Check Mail", 0, 0, System.Diagnostics.TraceEventType.Information, "Valid Emails Processed");
            Code.Common.Log(invalidEmails + ": invalid emails processed.", "Check Mail", 0, 0, System.Diagnostics.TraceEventType.Information, "Invalid Emails Processed");
            Code.Common.Log(nonActiveEmails + ": non-active project emails processed.", "Check Mail", 0, 0, System.Diagnostics.TraceEventType.Information, "Non-active Project Emails Processed");
        }

        

        private void RunCheck()
        {
            switch (ConfigurationManager.AppSettings["type"])
            {
                case "IMAP":
                    Imap(Convert.ToBoolean(ConfigurationManager.AppSettings["ssl"]));

                    break;
                case "POP":
                    Pop(Convert.ToBoolean(ConfigurationManager.AppSettings["ssl"]));
                    break;
            }

        }

        private void Imap(Boolean Ssl)
        {
            Imap4Client p = new Imap4Client();
            if (Ssl)
            {
                p.ConnectSsl(ConfigurationManager.AppSettings["host"], Convert.ToInt32(ConfigurationManager.AppSettings["port"]));
            }
            else
            {
                p.Connect(ConfigurationManager.AppSettings["host"], Convert.ToInt32(ConfigurationManager.AppSettings["port"]));
            }

            p.Login(ConfigurationManager.AppSettings["username"], ConfigurationManager.AppSettings["userpassword"]);

            if (p.Mailboxes["INBOX"].MessageCount > 0)
            {
                Dictionary<string, Hashtable> list = TractRecord.Code.DataAccess.ProjectEmailList();
                
                Mailbox inbox = p.SelectMailbox("INBOX");

                Mailbox archives;

                try
                {
                    archives = p.SelectMailbox("archives");
                }
                catch (Exception)
                {
                    archives = p.CreateMailbox("archives");
                }
                
                for (int a = 1; a < inbox.MessageCount + 1; a++)
                {
                    bool isValid = false;
                    bool isActive = false;
                    string projectName = string.Empty;
                    Guid projectId = Guid.Empty;

                    ArrayList emails = new ArrayList();

                    // retrieve first message
                    Message m = inbox.Fetch.MessageObject(1);

                    foreach (Address add in m.To)
                    {
                        emails.Add(add.Merged);
                        if (list.ContainsKey(add.Email))
                        {
                            isValid = true;
                            projectName = list[add.Email]["Name"].ToString();
                            projectId = (Guid)list[add.Email]["ProjectId"];
                            if ((bool)list[add.Email]["ActiveInd"])
                            {
                                isActive = true;
                            }
                        }
                    }

                    ListDictionary replacements = new ListDictionary();
                    replacements.Add("<%Name%>", m.From.Name);
                    replacements.Add("<%ProjectName%>", projectName);

                    if (isValid)
                    {
                        if (isActive)
                        {
                            //process email

                            replacements.Add("<%NumberOfFiles%>", m.Attachments.Count.ToString());
                            StringBuilder files = new StringBuilder();

                            if (m.Attachments.Count > 0)
                            {
                                Guid EmailId = Code.DataAccess.AddEmail(m.From.Email, string.Empty, string.Empty, m.Date, m.Subject, m.BodyHtml.Text);
                                
                                for (int b = 0; b < m.Attachments.Count; b++)
                                {
                                    try
                                    {
                                        MimePart att = m.Attachments[b];

                                        Code.DataAccess.AddFile(m.Date, projectId, string.Empty, EmailId, att.Filename, att.ContentType.MimeType, att.BinaryContent);

                                        files.AppendLine(att.Filename + " (" + att.Size.ToString("0,0") + " bytes)");
                                    }
                                    catch (Exception err)
                                    {
                                        Code.Common.Log("Unable to upload file " + m.Attachments[b].Filename + "\n" + err.ToString(), err.GetType().ToString(), 100, 0, System.Diagnostics.TraceEventType.Critical, "Upload File Error");
                                    }
                                }
                            }
                            
                            replacements.Add("<%Files%>", files.ToString());
                            validEmails++;
                            
                            WebCommon.GenerateEmailMessage(WebCommon.MailMessageType.ProjectAcceptedEmail, "RE:" + m.Subject, m.From.Email, replacements);
                            
                            //send alert mail
                            ForwardMessage(m, projectId, projectName);
                        }
                        else
                        {
                            nonActiveEmails++;
                            // respond to sender
                            WebCommon.GenerateEmailMessage(WebCommon.MailMessageType.ProjectNotAcceptingEmails, "RE:" + m.Subject, m.From.Email, replacements);
                        }
                    }
                    else
                    {
                        invalidEmails++;
                        replacements.Add("<%ProjectEmailAddress%>", string.Join(",", (string[])emails.ToArray(typeof(string))));
                        // respond to sender
                        WebCommon.GenerateEmailMessage(WebCommon.MailMessageType.InvalidProjectEmail , "RE:" + m.Subject, m.From.Email, replacements);
                    }
                    inbox.MoveMessage(1, "archives");
                    
                }
            }
            else
            {
                Code.Common.Log("No new emails.", "Check Mail", 0, 0, System.Diagnostics.TraceEventType.Information, "Check Mail");
            }


        }
        
        private void Pop(Boolean Ssl)
        {
            Pop3Client p = new Pop3Client();

            if (Ssl)
            {
                p.ConnectSsl(ConfigurationManager.AppSettings["host"], 
                    Convert.ToInt32(ConfigurationManager.AppSettings["port"]),
                    ConfigurationManager.AppSettings["username"],
                    ConfigurationManager.AppSettings["userpassword"]);
            }
            else
            {
                p.Connect(ConfigurationManager.AppSettings["host"],
                    Convert.ToInt32(ConfigurationManager.AppSettings["port"]),
                    ConfigurationManager.AppSettings["username"],
                    ConfigurationManager.AppSettings["userpassword"]);
            }
        }

        private void ForwardMessage(Message m, Guid ProjectId, String ProjectName)
        {

            try
            {
                Dictionary<string, Hashtable> list = TractRecord.Code.DataAccess.ProjectEmailList();


                List<Code.AttachedFile> files = new List<Code.AttachedFile>();

                for (int b = 0; b < m.Attachments.Count; b++)
                {
                    Code.AttachedFile f = new Code.AttachedFile();

                    f.ms = new System.IO.MemoryStream(m.Attachments[b].BinaryContent);
                    f.contenttype = m.Attachments[b].ContentType.MimeType;
                    f.filename = m.Attachments[b].Filename;

                    files.Add(f);
                }

                ListDictionary replacements = new ListDictionary();
                replacements.Add("<%Name%>", m.From.Name);
                replacements.Add("<%ProjectName%>", ProjectName);
                replacements.Add("<%ForwardedMessage%>", m.BodyText.Text);

                ArrayList To = new ArrayList();

                foreach (object email in Code.DataAccess.GetAlertEmails(ProjectId.ToString()))
                {
                    To.Add(email.ToString());
                }

                WebCommon.GenerateEmailMessage(WebCommon.MailMessageType.NewIncomingEmail, "FW:" + m.Subject, To, replacements, files);
                               

                //ServerCollection servers = new ServerCollection();
                //Configuration config = WebConfigurationManager.OpenWebConfiguration(HttpContext.Current.Request.ApplicationPath);
                //MailSettingsSectionGroup settings = (MailSettingsSectionGroup)config.GetSectionGroup("system.net/mailSettings");

                //ActiveUp.Net.Mail.Server server = new ActiveUp.Net.Mail.Server(settings.Smtp.Network.Host,
                //    settings.Smtp.Network.Port,
                //    settings.Smtp.Network.UserName,
                //    settings.Smtp.Network.Password);

                //servers.Add(server);

                //m.BodyText.Text = "From: " + m.From.Merged + Environment.NewLine +
                //    "Date: " + m.Date.ToString("ddd, dd MMM yyyy hh:mm:ss zzz") + Environment.NewLine + Environment.NewLine +
                //    m.BodyText.Text;

                //m.BodyHtml.Text = "From: " + m.From.Merged + "<br />" +
                //    "Date: " + m.Date.ToString("ddd, dd MMM yyyy hh:mm:ss zzz") + "<br />" + "<br />" +
                //    m.BodyHtml.Text;

                //m.From = new Address(settings.Smtp.From);
                //m.Subject = "FW:" + m.Subject;

                //m.To.Clear();

                //foreach (object email in Code.DataAccess.GetAlertEmails(ProjectId.ToString()))
                //{
                //    m.To.Add(email.ToString());
                //}

                //Code.Common.Log("Forwarding Email from Actor", "Forward Email");

                //SmtpClient.Send(m, servers);
            }
            catch (Exception ex)
            {
                Code.Common.Log(ex.ToString(), ex.GetType().ToString(), 100, 0, System.Diagnostics.TraceEventType.Critical, "Forward Email Error"); 
            }
        }
    }
}